import React, {
  InputHTMLAttributes,
  useState,
  useRef,
  forwardRef,
  useImperativeHandle,
  useEffect,
} from 'react';
import { useNewControllableValue } from '../../hooks/useControllableValue';
import classNames from 'classnames';
import { JUDGE_STATE, judgeType, baseName } from '../../type';
import Icon from '../icon/index';

export interface BaseInputProps {
  defaultProps?: string;
  className?: string;
  value?: string;
  type?: InputType;
  noHide?: boolean;
  judge?: InputJudge;
  title?: string;
}

type InputProps = BaseInputProps &
  Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;

type InputType = 'input' | 'block';

type InputJudge =
  | 'default'
  | 'mobilePhone'
  | 'adsl'
  | 'telphone'
  | 'pwd'
  | 'allIdCard'
  | 'name'
  | 'msgCode'
  | 'idCard'
  | 'imgCode';

export type InputRef = {
  clear: () => void;
  focus: () => void;
  blur: () => void;
};

export const Input = forwardRef<InputRef, InputProps>((props, ref) => {
  const {
    className,
    type,
    noHide,
    judge,
    onBlur,
    onFocus,
    title,
    prefix,
    ...restPros
  } = props;

  const eleRef = useRef<HTMLInputElement>(null);

  useImperativeHandle(ref, () => ({
    clear: () => {
      setValue('');
    },
    focus: () => {
      eleRef.current?.focus();
    },
    blur: () => {
      eleRef.current?.blur();
    },
  }));

  const idCity = useRef<{ [propsName: number]: string }>({
    11: '北京',
    12: '天津',
    13: '河北',
    14: '山西',
    15: '内蒙古',
    21: '辽宁',
    22: '吉林',
    23: '黑龙江',
    31: '上海',
    32: '江苏',
    33: '浙江',
    34: '安徽',
    35: '福建',
    36: '江西',
    37: '山东',
    41: '河南',
    42: '湖北',
    43: '湖南',
    44: '广东',
    45: '广西',
    46: '海南',
    50: '重庆',
    51: '四川',
    52: '贵州',
    53: '云南',
    54: '西藏',
    61: '陕西',
    62: '甘肃',
    63: '青海',
    64: '宁夏',
    65: '新疆',
    71: '台湾',
    81: '香港',
    82: '澳门',
    91: '国外',
  });

  const [firstInput, setFirstInput] = useState<boolean>(true);
  const [showHide, setShowHide] = useState<boolean>(true);
  const [judgeState, setJudgeState] = useState<judgeType>(JUDGE_STATE.STATIC);
  const hideJudge = useRef<string[]>(['pwd']);

  const [value, setValue] = useNewControllableValue({
    defaultValue: '',
  });

  useEffect(() => {
    judge == 'mobilePhone' &&
    (/^1[0-9]{0,}$/.test(value) || value === '') &&
    value.length == 11
      ? setJudgeState(() => JUDGE_STATE.SUCCESS)
      : setJudgeState(() => JUDGE_STATE.FAILED);

    judge == 'name' && /[\u4e00-\u9fa5]+$/.test(value) && value.length <= 10
      ? setJudgeState(() => JUDGE_STATE.SUCCESS)
      : setJudgeState(() => JUDGE_STATE.FAILED);

    judge == 'pwd' &&
    (/^[0-9]{0,}$/.test(value) || value === '') &&
    value.length == 6
      ? setJudgeState(() => JUDGE_STATE.SUCCESS)
      : setJudgeState(() => JUDGE_STATE.FAILED);

    if (judge == 'allIdCard') {
      if (!/(^\d{15}$)|(^\d{17}(\d|X|x)$)/.test(value)) {
        setJudgeState(() => JUDGE_STATE.FAILED);
        // setDesc('身份证长度或格式错误')
        return;
      }
      if (!idCity.current[parseInt(value.substr(0, 2))]) {
        setJudgeState(() => JUDGE_STATE.FAILED);
        // setDesc('身份证地区非法')
        return;
      }
      let sum = 0,
        weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
        codes = '10X98765432';
      for (let i = 0; i < value.length - 1; i++) {
        //@ts-ignore
        sum += value[i] * weights[i];
      }
      let last = codes[sum % 11]; //计算出来的最后一位身份证号码
      if (value[value.length - 1] != last) {
        setJudgeState(() => JUDGE_STATE.FAILED);
        // setDesc('身份证非法')
        return;
      }
      setJudgeState(() => JUDGE_STATE.SUCCESS);
    }
  }, [value]);

  const classes = classNames(`${prefix}-input`, className, {
    [`${prefix}-input-${type}`]: type,
    failed: judgeState === JUDGE_STATE.FAILED && !firstInput,
  });

  return (
    <div className={classes}>
      {title && <label>{title}</label>}
      <div className={`${prefix}-input-zone`}>
        {type == 'input' && (
          <input
            type={
              noHide
                ? ''
                : hideJudge.current.indexOf(judge) !== -1 && showHide
                ? 'password'
                : ''
            }
            value={value}
            onChange={e => setValue(e.target.value)}
            onFocus={e => {
              onFocus && onFocus(e);
              // setFirstInput(() => false)
            }}
            onBlur={e => {
              onBlur && onBlur(e);
              setFirstInput(() => false);
            }}
            {...restPros}
          />
        )}
        {type === 'block' && <div>{value}</div>}
        <span></span>
      </div>
      {!noHide && hideJudge.current.indexOf(judge) !== -1 && (
        <Icon
          type="showHide"
          onClick={() => setShowHide(() => !showHide)}
          trigger={showHide}
        />
      )}
    </div>
  );
});

Input.defaultProps = {
  type: 'input',
  judge: 'default',
  noHide: false,
  prefix: baseName,
};
